home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) __version__ = '12.0' __title__ = 'Services and Status System Tray dBus Child/Parent Process' __mod__ = 'hpssd' __doc__ = 'Provides persistent data and event services to HPLIP client applications. Required to be running for PC send fax, optional in all other cases.' import sys import struct import os import time import getopt import select import signal import tempfile from cPickle import loads, HIGHEST_PROTOCOL from base.g import * from base.codes import * from base import utils, device, status, models try: from dbus import lowlevel, SystemBus, SessionBus import dbus.service as dbus from dbus.mainloop.glib import DBusGMainLoop from gobject import MainLoop, timeout_add, threads_init, io_add_watch, IO_IN dbus_loaded = True except ImportError: log.error('dbus failed to load (python-dbus ver. 0.80+ required). Exiting...') dbus_loaded = False sys.exit(1) import warnings warnings.simplefilter('ignore', DeprecationWarning) PIPE_BUF = 4096 (dbus_loop, main_loop) = (None, None) system_bus = None session_bus = None (w1, w2, r3) = (None, None, None) devices = { } class DeviceCache(object): def __init__(self, model = ''): self.history = utils.RingBuffer(prop.history_size) self.model = models.normalizeModelName(model) self.cache = { } self.faxes = { } self.dq = { } self.backoff_counter = 0 self.backoff_countdown = 0 self.polling = False class StatusService(dbus.service.Object): def __init__(self, name, object_path): dbus.service.Object.__init__(self, name, object_path) def GetHistory(self, device_uri): log.debug("GetHistory('%s')" % device_uri) send_systray_blip() try: devices[device_uri] except KeyError: return (device_uri, []) h = devices[device_uri].history.get() log.debug('%d events in history:' % len(h)) [ x.debug() for x in h ] return ([], [ x.as_tuple() for x in h ]) GetHistory = dbus.service.method('com.hplip.StatusService', in_signature = 's', out_signature = 'sa(ssisisd)')(GetHistory) def GetStatus(self, device_uri): log.debug("GetStatus('%s')" % device_uri) send_systray_blip() try: devices[device_uri] except KeyError: return (device_uri, { }) t = { } dq = devices[device_uri].dq [ t.setdefault(x, str(dq[x])) for x in dq.keys() ] log.debug(t) return (device_uri, t) GetStatus = dbus.service.method('com.hplip.StatusService', in_signature = 's', out_signature = 'sa{ss}')(GetStatus) def SetCachedIntValue(self, device_uri, key, value): log.debug("SetCachedIntValue('%s', '%s', %d)" % (device_uri, key, value)) if check_device(device_uri) == ERROR_SUCCESS: devices[device_uri].cache[key] = value return value return -1 SetCachedIntValue = dbus.service.method('com.hplip.StatusService', in_signature = 'ssi', out_signature = 'i')(SetCachedIntValue) def GetCachedIntValue(self, device_uri, key): try: ret = devices[device_uri].cache[key] except KeyError: ret = -1 log.debug("GetCachedIntValue('%s', '%s') --> %d" % (device_uri, key, ret)) return ret GetCachedIntValue = dbus.service.method('com.hplip.StatusService', in_signature = 'ss', out_signature = 'i')(GetCachedIntValue) def SetCachedStrValue(self, device_uri, key, value): log.debug("SetCachedStrValue('%s', '%s', '%s')" % (device_uri, key, value)) if check_device(device_uri) == ERROR_SUCCESS: devices[device_uri].cache[key] = value return value return '' SetCachedStrValue = dbus.service.method('com.hplip.StatusService', in_signature = 'sss', out_signature = 's')(SetCachedStrValue) def GetCachedStrValue(self, device_uri, key): try: ret = devices[device_uri].cache[key] except KeyError: ret = '' log.debug("GetCachedStrValue('%s', '%s') --> %s" % (device_uri, key, ret)) return ret GetCachedStrValue = dbus.service.method('com.hplip.StatusService', in_signature = 'ss', out_signature = 's')(GetCachedStrValue) def CheckForWaitingFax(self, device_uri, username, job_id = 0): log.debug("CheckForWaitingFax('%s', '%s', %d)" % (device_uri, username, job_id)) send_systray_blip() r = (device_uri, '', 0, username, job_id, '', 0, '') check_device(device_uri) show_waiting_faxes(device_uri) if job_id: try: devices[device_uri].faxes[(username, job_id)] except KeyError: return r return self.check_for_waiting_fax_return(device_uri, username, job_id) job_id for u, j in devices[device_uri].faxes.keys(): if u == username: return self.check_for_waiting_fax_return(device_uri, u, j) return r CheckForWaitingFax = dbus.service.method('com.hplip.StatusService', in_signature = 'ssi', out_signature = 'ssisisds')(CheckForWaitingFax) def check_for_waiting_fax_return(self, d, u, j): log.debug('Fax (username=%s, jobid=%d) removed from faxes and returned to caller.' % (u, j)) r = devices[d].faxes[(u, j)].as_tuple() del devices[d].faxes[(u, j)] show_waiting_faxes(d) return r def SendEvent(self, device_uri, printer_name, event_code, username, job_id, title): event = device.Event(device_uri, printer_name, event_code, username, job_id, title) handle_event(event) SendEvent = dbus.service.method('com.hplip.StatusService', in_signature = 'ssisis', out_signature = '')(SendEvent) def check_device(device_uri): try: devices[device_uri] except KeyError: log.debug('New device: %s' % device_uri) try: (back_end, is_hp, bus, model, serial, dev_file, host, zc, port) = device.parseDeviceURI(device_uri) except Error: log.debug('Invalid device URI: %s' % device_uri) return ERROR_INVALID_DEVICE_URI devices[device_uri] = DeviceCache(model) return ERROR_SUCCESS def create_history(event): history = devices[event.device_uri].history.get() if history and history[-1].event_code == event.event_code: log.debug('Duplicate event. Replacing previous event.') devices[event.device_uri].history.replace(event) return True devices[event.device_uri].history.append(event) return False def handle_fax_event(event, pipe_name): if event.event_code == EVENT_FAX_RENDER_COMPLETE and event.username == prop.username: (fax_file_fd, fax_file_name) = tempfile.mkstemp(prefix = 'hpfax-') pipe = os.open(pipe_name, os.O_RDONLY) bytes_read = 0 while True: data = os.read(pipe, PIPE_BUF) if not data: break os.write(fax_file_fd, data) bytes_read += len(data) log.debug('Saved %d bytes to file %s' % (bytes_read, fax_file_name)) os.close(pipe) os.close(fax_file_fd) devices[event.device_uri].faxes[(event.username, event.job_id)] = device.FaxEvent(fax_file_name, event) show_waiting_faxes(event.device_uri) try: os.waitpid(-1, os.WNOHANG) except OSError: pass (ok, lock_file) = utils.lock_app('hp-sendfax-%s' % event.printer_name, True) if ok: utils.unlock(lock_file) path = utils.which('hp-sendfax') if path: path = os.path.join(path, 'hp-sendfax') else: log.error('Unable to find hp-sendfax on PATH.') return None path.debug('Running hp-sendfax: %s --printer=%s' % (path, event.printer_name)) os.spawnlp(os.P_NOWAIT, path, 'hp-sendfax', '--printer=%s' % event.printer_name) else: log.debug('hp-sendfax is running. Waiting for CheckForWaitingFax() call.') else: log.warn('Not handled!') def show_waiting_faxes(d): f = devices[d].faxes if not len(f): log.debug('No faxes waiting for %s' % d) elif len(f) == 1: log.debug('1 fax waiting for %s:' % d) else: log.debug('%d faxes waiting for %s:' % (len(f), d)) [ f[x].debug() for x in f ] def handle_hpdio_event(event, bytes_written): log.debug('Reading %d bytes from hpdio pipe...' % bytes_written) (total_read, data) = (0, '') while True: (r, w, e) = select.select([ r3], [], [ r3], 0) if not r: break x = os.read(r3, PIPE_BUF) if not x: break data = ''.join([ data, x]) total_read += len(x) if total_read == bytes_written: break continue log.debug('Read %d bytes' % total_read) if total_read == bytes_written: dq = loads(data) if check_device(event.device_uri) == ERROR_SUCCESS: devices[event.device_uri].dq = dq.copy() handle_event(device.Event(event.device_uri, '', dq.get('status-code', STATUS_PRINTER_IDLE), prop.username, 0, '')) send_toolbox_event(event, EVENT_DEVICE_UPDATE_REPLY) def handle_event(event, more_args = None): log.debug('Handling event...') if more_args is None: more_args = [] event.debug() if event.device_uri and check_device(event.device_uri) != ERROR_SUCCESS: return None if event.event_code > EVENT_MAX_EVENT: event.event_code = status.MapPJLErrorCode(event.event_code) if event.event_code < EVENT_MIN_USER_EVENT: pass elif event.event_code <= event.event_code: pass elif event.event_code <= EVENT_MAX_USER_EVENT: if event.device_uri: dup_event = create_history(event) if event.event_code in (EVENT_DEVICE_STOP_POLLING, EVENT_START_MAINT_JOB, EVENT_START_COPY_JOB, EVENT_START_FAX_JOB, EVENT_START_PRINT_JOB): pass elif event.event_code in (EVENT_DEVICE_START_POLLING, EVENT_END_MAINT_JOB, EVENT_END_COPY_JOB, EVENT_END_FAX_JOB, EVENT_END_PRINT_JOB, EVENT_PRINT_FAILED_MISSING_PLUGIN, EVENT_SCANNER_FAIL, EVENT_END_SCAN_JOB, EVENT_SCAN_FAILED_MISSING_PLUGIN, EVENT_FAX_JOB_FAIL, EVENT_FAX_JOB_CANCELED, EVENT_FAX_FAILED_MISSING_PLUGIN, EVENT_COPY_JOB_FAIL, EVENT_COPY_JOB_CANCELED): pass if not dup_event: send_event_to_systray_ui(event) send_toolbox_event(event, EVENT_HISTORY_UPDATE) elif event.event_code <= event.event_code: pass elif event.event_code <= EVENT_FAX_MAX and more_args: log.debug('Fax event') pipe_name = str(more_args[0]) handle_fax_event(event, pipe_name) elif event.event_code == EVENT_USER_CONFIGURATION_CHANGED: send_event_to_systray_ui(event) elif event.event_code == EVENT_SYS_CONFIGURATION_CHANGED: send_event_to_systray_ui(event) elif event.event_code in (EVENT_DEVICE_UPDATE_REQUESTED,): send_event_to_hpdio(event) elif event.event_code in (EVENT_DEVICE_UPDATE_ACTIVE, EVENT_DEVICE_UPDATE_INACTIVE): send_event_to_systray_ui(event) elif event.event_code == EVENT_DEVICE_UPDATE_REPLY: bytes_written = int(more_args[1]) handle_hpdio_event(event, bytes_written) elif event.event_code == EVENT_SYSTEMTRAY_EXIT: send_event_to_hpdio(event) send_toolbox_event(event) send_event_to_systray_ui(event) log.debug('Exiting') main_loop.quit() elif event.event_code in (EVENT_DEVICE_START_POLLING, EVENT_DEVICE_STOP_POLLING): pass else: log.error('Unhandled event: %d' % event.event_code) def send_systray_blip(): send_event_to_systray_ui(device.Event('', '', EVENT_DEVICE_UPDATE_BLIP)) def send_event_to_systray_ui(event, event_code = None): e = event.copy() if event_code is not None: e.event_code = event_code e.send_via_pipe(w1, 'systemtray') def send_event_to_hpdio(event): event.send_via_pipe(w2, 'hpdio') def send_toolbox_event(event, event_code = None): e = event.copy() if event_code is not None: e.event_code = event_code e.send_via_dbus(session_bus, 'com.hplip.Toolbox') def handle_signal(typ, *args, **kwds): if kwds['interface'] == 'com.hplip.StatusService' and kwds['member'] == 'Event': event = device.Event(*args[:6]) return handle_event(event, args[6:]) def handle_system_signal(*args, **kwds): return handle_signal('system', *args, **kwds) def handle_session_signal(*args, **kwds): return handle_signal('session', *args, **kwds) def run(write_pipe1 = None, write_pipe2 = None, read_pipe3 = None): global w1, w2, r3, dbus_loop, main_loop, system_bus, session_bus log.set_module('hp-systray(hpssd)') log.debug('PID=%d' % os.getpid()) w1 = write_pipe1 w2 = write_pipe2 r3 = read_pipe3 dbus_loop = DBusGMainLoop(set_as_default = True) main_loop = MainLoop() try: system_bus = SystemBus(mainloop = dbus_loop) except dbus.exceptions.DBusException: e = None log.error('Unable to connect to dbus system bus. Exiting.') sys.exit(1) try: session_bus = dbus.SessionBus() except dbus.exceptions.DBusException: e = None if os.getuid() != 0: log.error('Unable to connect to dbus session bus. Exiting.') sys.exit(1) else: log.error('Unable to connect to dbus session bus (running as root?)') sys.exit(1) except: os.getuid() != 0 system_bus.add_signal_receiver(handle_system_signal, sender_keyword = 'sender', destination_keyword = 'dest', interface_keyword = 'interface', member_keyword = 'member', path_keyword = 'path') session_bus.add_signal_receiver(handle_session_signal, sender_keyword = 'sender', destination_keyword = 'dest', interface_keyword = 'interface', member_keyword = 'member', path_keyword = 'path') session_name = dbus.service.BusName('com.hplip.StatusService', session_bus) status_service = StatusService(session_name, '/com/hplip/StatusService') log.debug('Entering main dbus loop...') try: main_loop.run() except KeyboardInterrupt: log.debug('Ctrl-C: Exiting...')